home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / presto / presto10.lha / src / atomic_int.h < prev    next >
C/C++ Source or Header  |  1991-12-11  |  8KB  |  311 lines

  1. #ifndef __presto__atomic_int_h__
  2. #define __presto__atomic_int_h__
  3.  
  4. //
  5. // Atomic ints are good for counters, etc...  All integer operations
  6. // on them are defined.
  7. //
  8. // Modification History:
  9. //
  10. // 09-Aug-1991 PBD
  11. // Removed non-ANSI macros and expanded in-place.
  12. //
  13. // 14-Jan-1989  JEF
  14. // Added 'value' member function to both classes.
  15. //
  16. // 04-Jan-1989  JEF
  17. // Include lock/unlock pair around operator INT in both classes.
  18. //
  19. // 28-Dec-1989  JEF
  20. // Add class HC_AtomicInt.  This new version of an atomic integer utilizes
  21. // the HC_Spinlock, providing faster atomic integer operations when there is
  22. // high contention for the atomic integer.
  23. //
  24.  
  25. //
  26. //  Original atomic integer class.
  27. //
  28. class AtomicInt    {
  29.     Spinlock    ai_lock;
  30.     int         ai_val;
  31. public:
  32.     AtomicInt()
  33.         { ai_val = 0; }
  34.     AtomicInt(int x)
  35.         { ai_val = x; }
  36.     AtomicInt(AtomicInt& x)        // should we lock x?
  37.         { ai_val = x.ai_val;}
  38.     ~AtomicInt()
  39.         { unlock(); }
  40.     operator int()
  41.         { lock();   register int tmp = ai_val;   unlock();
  42.           return tmp; }
  43.     void lock()             // Careful.... 
  44.         { ai_lock.lock(); }
  45.     void unlock()
  46.         { ai_lock.unlock(); }
  47.     int&    val()            // use at your own risk
  48.         { return ai_val; }
  49.     int    value()                 // retrieve current value safely
  50.         { lock();   register int tmp = ai_val;   unlock();
  51.           return tmp; }
  52.     inline int operator= (int x)    
  53.     { 
  54.           lock();  register int tmp = ai_val = x; unlock(); 
  55.           return tmp; 
  56.         }
  57.  
  58.     inline int operator+= (int x)    
  59.     { 
  60.           lock();  register int tmp = ai_val += x; unlock(); 
  61.           return tmp; 
  62.         }
  63.  
  64.     inline int operator*= (int x)    
  65.     { 
  66.           lock();  register int tmp = ai_val *= x; unlock(); 
  67.           return tmp; 
  68.         }
  69.  
  70.     inline int operator/= (int x)    
  71.     { 
  72.           lock();  register int tmp = ai_val /= x; unlock(); 
  73.           return tmp; 
  74.         }
  75.  
  76.     inline int operator%= (int x)    
  77.     { 
  78.           lock();  register int tmp = ai_val %= x; unlock(); 
  79.           return tmp; 
  80.         }
  81.  
  82.     inline int operator^= (int x)    
  83.     { 
  84.           lock();  register int tmp = ai_val ^= x; unlock(); 
  85.           return tmp; 
  86.         }
  87.  
  88.     inline int operator&= (int x)    
  89.     { 
  90.           lock();  register int tmp = ai_val &= x; unlock(); 
  91.           return tmp; 
  92.         }
  93.  
  94.     inline int operator|= (int x)    
  95.     { 
  96.           lock();  register int tmp = ai_val |= x; unlock(); 
  97.           return tmp; 
  98.         }
  99.  
  100.     inline int operator<<= (int x)    
  101.     { 
  102.           lock();  register int tmp = ai_val <<= x; unlock(); 
  103.           return tmp; 
  104.         }
  105.  
  106.     inline int operator>>= (int x)    
  107.     { 
  108.           lock();  register int tmp = ai_val >>= x; unlock(); 
  109.           return tmp; 
  110.         }
  111.  
  112.  
  113.     inline int operator++ ()    // prefix
  114.     { 
  115.           lock();  register int tmp = ++ai_val; unlock(); 
  116.           return tmp; 
  117.         }
  118.  
  119. #ifdef __DECCXX /* or rather, an ARM compliant compiler */
  120.     inline int operator++ (int x)     // postfix
  121.     { 
  122.           lock();  register int tmp = ai_val++; unlock(); 
  123.           return tmp; 
  124.         }
  125.  
  126. #endif /* _DECCXX */
  127.     inline int operator-- ()    // prefix
  128.     { 
  129.           lock();  register int tmp = --ai_val; unlock(); 
  130.           return tmp; 
  131.         }
  132.  
  133. #ifdef __DECCXX /* as above */
  134.     inline int operator-- (int x)    // postfix
  135.     { 
  136.           lock();  register int tmp = ai_val--; unlock(); 
  137.           return tmp; 
  138.         }
  139. #endif /* __DECCXX */
  140.  
  141. };
  142.  
  143. #ifdef sequent
  144. #ifdef i386
  145.  
  146. //
  147. //  Atomic integer class specialized for use in high-contention situations.
  148. //
  149. //  The best 'C++' way to do this is probably to make the AtomicInt functions
  150. //  lock and unlock be virtual, and to then derive class HC_AtomicInt from
  151. //  class AtomicInt, providing new lock and unlock functions specific to the
  152. //  HC_Spinlock (as given below).  However, the performance of the member
  153. //  functions of the new derived class is poor compared to the performance
  154. //  realized when a new base class is created (by copying and modifying the
  155. //  original base class).  In the interest of speed, we'll go with the new
  156. //  base class instead of the derived class.
  157. //
  158.  
  159. //
  160. //  The clean (but SLOW) way...  (note - must make ai_val in base class
  161. //  be protected).
  162. //
  163. //class HC_AtomicInt : public AtomicInt    {
  164. //    HC_Spinlock    hc_ai_lock;
  165. //public:
  166. //    HC_AtomicInt ();                         // base class constructor
  167. //    HC_AtomicInt (int x) : (x) {}            //   is called to do
  168. //    HC_AtomicInt (AtomicInt& x) : (x) {}     //   all the work
  169. //
  170. //    ~HC_AtomicInt ()
  171. //        { unlock(); }
  172. //
  173. //    //
  174. //      //  Make base class lock and unlock functions be virtual.  Then
  175. //    //  override them with new versions specific to the high-contention
  176. //      //  spinlock.
  177. //    //
  178. //    void lock ()                             // Careful....
  179. //        {
  180. //          hc_ai_lock.lock ();
  181. //                cout << "ai - derived class lock (HC_Spinlock.lock)\n";
  182. //          cout.flush ();
  183. //            }
  184. //
  185. //    void unlock ()
  186. //        {
  187. //              cout << "ai - derived class unlock (HC_Spinlock.unlock)\n";
  188. //                cout.flush ();
  189. //                hc_ai_lock.unlock();
  190. //            }
  191. //};
  192.  
  193.  
  194. //
  195. //  The fast way...
  196. //
  197. class HC_AtomicInt    {
  198.     HC_Spinlock    ai_lock;
  199.     int         ai_val;
  200. public:
  201.     HC_AtomicInt()
  202.         { ai_val = 0; }
  203.     HC_AtomicInt(int x)
  204.         { ai_val = x; }
  205.     HC_AtomicInt(HC_AtomicInt& x)        // should we lock x?
  206.         { ai_val = x.ai_val;}
  207.     ~HC_AtomicInt()
  208.         { unlock(); }
  209.     operator int()
  210.         { lock();   register int tmp = ai_val;   unlock();
  211.           return tmp; }
  212.     void lock()             // Careful....
  213.         { ai_lock.lock(); }
  214.     void unlock()
  215.         { ai_lock.unlock(); }
  216.     int&    val()            // use at your own risk
  217.         { return ai_val; }
  218.     int    value()                 // retrieve current value safely
  219.         { lock();   register int tmp = ai_val;   unlock();
  220.           return tmp; }
  221.  
  222.     inline int operator= (int x)    
  223.     { 
  224.           lock();  register int tmp = ai_val = x; unlock(); 
  225.           return tmp; 
  226.         }
  227.  
  228.     inline int operator+= (int x)    
  229.     { 
  230.           lock();  register int tmp = ai_val += x; unlock(); 
  231.           return tmp; 
  232.         }
  233.  
  234.     inline int operator*= (int x)    
  235.     { 
  236.           lock();  register int tmp = ai_val *= x; unlock(); 
  237.           return tmp; 
  238.         }
  239.  
  240.     inline int operator/= (int x)    
  241.     { 
  242.           lock();  register int tmp = ai_val /= x; unlock(); 
  243.           return tmp; 
  244.         }
  245.  
  246.     inline int operator%= (int x)    
  247.     { 
  248.           lock();  register int tmp = ai_val %= x; unlock(); 
  249.           return tmp; 
  250.         }
  251.  
  252.     inline int operator^= (int x)    
  253.     { 
  254.           lock();  register int tmp = ai_val ^= x; unlock(); 
  255.           return tmp; 
  256.         }
  257.  
  258.     inline int operator&= (int x)    
  259.     { 
  260.           lock();  register int tmp = ai_val &= x; unlock(); 
  261.           return tmp; 
  262.         }
  263.  
  264.     inline int operator|= (int x)    
  265.     { 
  266.           lock();  register int tmp = ai_val |= x; unlock(); 
  267.           return tmp; 
  268.         }
  269.  
  270.     inline int operator<<= (int x)    
  271.     { 
  272.           lock();  register int tmp = ai_val <<= x; unlock(); 
  273.           return tmp; 
  274.         }
  275.  
  276.     inline int operator>>= (int x)    
  277.     { 
  278.           lock();  register int tmp = ai_val >>= x; unlock(); 
  279.           return tmp; 
  280.         }
  281.  
  282.     inline int operator++ ()    
  283.     { 
  284.           lock();  register int tmp = ai_val++; unlock(); 
  285.           return tmp; 
  286.         }
  287.  
  288.     inline int operator-- ()    
  289.     { 
  290.           lock();  register int tmp = ai_val--; unlock(); 
  291.           return tmp; 
  292.         }
  293.  
  294.     int    preinc()
  295.         { lock();   register int tmp = ++ai_val;   unlock();
  296.           return tmp; }
  297.     int    postinc()
  298.         { lock();   register int tmp = ai_val++;   unlock();
  299.           return tmp; }
  300.     int    predec()
  301.         { lock();   register int tmp = --ai_val;   unlock();
  302.           return tmp; }
  303.     int    postdec()
  304.         { lock();   register int tmp = ai_val--;   unlock();
  305.           return tmp; }        
  306.     // Should probably have the rest of the operators here too...
  307. };
  308. #endif /* i386 */
  309. #endif /* sequent */
  310. #endif /* __presto__atomic_int_h__ */
  311.